﻿using System;
using System.Collections;
using System.Collections.Generic;
using BehaviorDesigner.Runtime;
using BehaviorDesigner.Runtime.Tasks;
using TMPro;
using UnityEngine;
using UnityEngine.UI;


[AddComponentMenu("ProjectCodes/Enemies/Level1/Minions/Sorcerer")]
public class BattleEnemyEntity : EnemyEntity
{
    private BehaviorTree _behaviorTree;

    [Header("持有卡牌的参数")]
    public EnemyEntityData entityData;
    
    /********** HP条的参数 **********/
    [Header("血量条的参数")]
    public GameObject _hpBar;
    public TextMeshProUGUI _hpCountText;
    public Image _shieldImage;
    public TextMeshProUGUI _shieldCountText;
    public DisplayDamageNumber damageDrawer;
    
    private GameObject _hpBlockPrefab;

    protected int bestApproachDistance = 0;

    private GameSession _gameSession;

    public override void FlushStatus()
    {
        _gameSession.FlushHpBar(_hp, _hp_max, _hpBar);
        _gameSession.FlushHpText(_hpCountText, _hp);
        _gameSession.FlushShieldText(_shieldCountText, _shieldImage, _shield);
    }
    
    private void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireCube(transform.position, new Vector3(move * 2.5f, move * 2.5f));
    }

    private void Awake()
    {
        _animator = GetComponent<Animator>();
        m_spriteRenderer = GetComponent<SpriteRenderer>();
        
        _hpBlockPrefab = Resources.Load<GameObject>("Prefabs/LifeBlock");

        _gameSession = GameObject.FindGameObjectWithTag(StaticDataManager.GAME_SESSION_TAG).GetComponent<GameSession>();

        deathEvent += _gameSession.EntityDeath;
    }

    private void Start()
    {
        InitBaseParam();
        InitCardManager();
        InitBehaviorTree();
        AddToEnemyList();
        InitialMovement();
        
        _status = EntityStatusEnum.Initialize;
        
        _gameSession.InitialHpBar(_hpBar);
        FlushStatus();
        _gameSession.AddEntity(EntityType.Enemy);
        
        GetCurrentTile();
    }

    private void InitializeBehaviourTreeVariables()
    {
        if (_behaviorTree == null)
        {
            _behaviorTree = GetComponent<BehaviorTree>();
        }
        
        _behaviorTree.enabled = false;
        _status = EntityStatusEnum.Idle;
    }
    
    private void Update()
    {
        if (isDead)
        {
            return;
        }
        
        switch (_status)
        {
            case EntityStatusEnum.Initialize:
                InitializeBehaviourTreeVariables();
                break;
            case EntityStatusEnum.Idle:
                break;
            case EntityStatusEnum.Thinking:
                Thinking();
                break;
            case EntityStatusEnum.Moving:
                Moving();
                break;
            case EntityStatusEnum.Beaten:
                CheckHP();

                FlushStatus();

                if (_hp > 0)
                {
                    _animator.Play("Hit");
                    _status = EntityStatusEnum.Idle;
                }
                else
                {
                    _animator.Play("Dead");
                    _status = EntityStatusEnum.Destroy;
                }

                break;
            case EntityStatusEnum.Attack:
                
                break;
            case EntityStatusEnum.Guard:
                break;
            case EntityStatusEnum.OverWatching:
                break;
            case EntityStatusEnum.Destroy:
                isDead = true;
                releaseCurrentTile();
                
                deathEvent?.Invoke(EntityType.Enemy);
                
                Destroy(this.gameObject, 1f);
                break;
            case EntityStatusEnum.TurnStart:
                TurnStart();
                break;
            case EntityStatusEnum.TurnEnd:
                TurnEnd();
                break;
            default:
                throw new ArgumentOutOfRangeException();
        }
    }

    public void releaseCurrentTile()
    {
        currentStandingTile.isOcupied = false;
    }

    public void ExecuteCurrentCard()
    {
        try
        {
            var receiver = GameObject.FindGameObjectWithTag(StaticDataManager.PLAYER_TAG);
            
            BattleResolver.ExecuteCardAction(
                _cardManager.currentDeckInstances[DeckType.Action][0].GetComponent<BasicCard>().pairData.cardData.nextActions, 
                gameObject, 
                receiver, 
                Vector3.zero);
            
            //_animator.Play("Attack");
        }
        catch (Exception e)
        {
            Debug.Log(e);
        }
    }

    private void InitBehaviorTree()
    {
        _behaviorTree = GetComponent<BehaviorTree>();   
    }
    
    public override void EndTurn()
    {
        base.EndTurn();

        _behaviorTree.DisableBehavior();
        
        _status = EntityStatusEnum.Idle;
    }

    public override void DealDamage(int damage)
    {
        base.DealDamage(damage);
        
        damageDrawer.DrawDamagedNumber(-damage);
    }

    public override void StartTurn()
    {
        _status = EntityStatusEnum.TurnStart;
        Debug.Log($"Enemy :: 设置的TurnStart");
        _behaviorTree.SetVariableValue("currentState", _status);
    }

    public void Thinking()
    {
        // TODO 思考中
        // TODO 决定了要先移动

        if (_behaviorTree.enabled == false && _status != EntityStatusEnum.TurnEnd)
        {
            _behaviorTree.EnableBehavior();
        }

    }

    public void SetTurnEnd()
    {
        _status = EntityStatusEnum.TurnEnd;
    }

    public void Moving()
    {
        _status = EntityStatusEnum.Moving;
        Debug.Log($"Enemy :: 设置的Moving");
        _behaviorTree.SetVariableValue("currentState", _status);
    }
    
    private void InitBaseParam()
    {
        _hp_max = entityData.maxHP;
        _hp = _hp_max;

        _ap_max = entityData.maxAP;
        _ap = _ap_max;

        _fp_max = entityData.maxFP;
        _fp = _fp_max;

        _mp_max = entityData.maxMP;
        _mp = _mp_max;
        
        move = _mp_max;
    }
    
    private void InitCardManager()
    {
        _cardManager = new CardManager(this);

        _cardManager.InitialDeck(entityData, isNeedResetDefaultDeck: true);
        _cardManager.BattleStart();
    }
    
    public bool PickCardFromRemainDeck(DeckType deckType)
    {
        Debug.Log("从抽卡区抽卡");

        bool isCanDrawCard;

        Debug.Log($"Enemy Action :: {_cardManager.cardInstances[DeckType.Action].Count}");
        Debug.Log($"Enemy Fixed :: {_cardManager.cardInstances[DeckType.Fixed].Count}");
        
        if (_cardManager.remainDeckInstances[deckType].Count > 0)
        {
            Debug.Log("从抽卡区有卡牌剩余，可以抽卡");
            isCanDrawCard = true;
        }
        else
        {
            Debug.Log("从抽卡区没有卡牌剩余");
            isCanDrawCard = false;
        }

        Debug.Log($"Enemy :: {isCanDrawCard}");
        
        if (isCanDrawCard)
        {
            Debug.Log("可以进行抽卡");
            GameObject card = _cardManager.remainDeckInstances[deckType].Pop();
            _cardManager.currentDeckInstances[deckType].Add(card);
            
            _behaviorTree.SetVariable("castCardInstance", new SharedGameObject() { Value = card });
            
            Debug.Log($"从持卡区抽取一张 {deckType} 卡，" +
                      $"当前手牌区的卡牌为：{_cardManager.currentDeckInstances[deckType].Count}, " +
                      $"持卡区的剩余卡牌数为: {_cardManager.remainDeckInstances[deckType].Count}");
        }
        else
        {
            Debug.Log("抽卡区没有卡牌剩余，无法继续抽卡");
        }

        return isCanDrawCard;
    }

    public override void TurnEnd()
    {
        EndTurn();
        
        TurnManager.EndTurn();
    }

    protected override void TurnStart()
    {
        // TODO 这里应该是需要thinking的
        _status = EntityStatusEnum.Thinking;
    }
    
    public void RecycleCard(DeckType deckType)
    {
        while (_cardManager.recycleDeckInstances[deckType].Count > 0)
        {
            _cardManager.remainDeckInstances[deckType].Add(_cardManager.recycleDeckInstances[deckType].Pop());
        }
    }

    private void AddToEnemyList()
    {
        GameObject.FindGameObjectWithTag(StaticDataManager.ENEMY_MANAGER_TAG).GetComponent<EnemyManager>().AddEnemy(gameObject);
    }

    private void RemoveFromEnemyList()
    {
        GameObject.FindGameObjectWithTag(StaticDataManager.ENEMY_MANAGER_TAG).GetComponent<EnemyManager>().RemoveEnemy(gameObject);
    }

    #region Behaviours

    public bool PickCardFromActionDeck()
    {
        return PickCardFromRemainDeck(DeckType.Action);
    }
    
    public bool PickCardFromFixedDeck()
    {
        return PickCardFromRemainDeck(DeckType.Fixed);
    }

    public void RecycleCardOfFixed()
    {
        RecycleCard(DeckType.Fixed);
    }

    public void RecycleCardOfAction()
    {
        RecycleCard(DeckType.Action);
    }
    
    public bool isActionCardInHoldingDeck()
    {
        return _cardManager.currentDeckInstances[DeckType.Action].Count > 0;
    }

    public bool isFixedCardInHoldingDeck()
    {
        return _cardManager.currentDeckInstances[DeckType.Fixed].Count > 0;
    }
    #endregion
}